package com.example.administrator.newxlmedical;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.PopupWindow;
import android.widget.TextView;

import com.example.administrator.baseproject.BaseActivity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import adapters.CommonStateErrorAdapter;
import beans.CheckHospitalBean;
import beans.CheckSureBean;
import beans.GoodsDetailsBean;
import beans.NewUserInfoBean;
import beans.OperateGoodsDetailsBean;
import beans.RfidListBean;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import constants.Constants;
import constants.HandlerConstant;
import customhandler.MyHandler;
import fragments.CheckErrorFragment;
import fragments.CheckFragment;
import fragments.TakeErrorFragment;
import fragments.TakeFragment;
import netframe.GetRetrofit;
import netframe.MyAction1;
import netframe.NetAddress;
import netframe.NetReconnectFunc1;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;
import rx.observables.GroupedObservable;
import rx.schedulers.Schedulers;
import singleton.SingletonClass;
import sqlite.MySQLiteOpenHelper;
import utils.ActivityUtil;
import utils.CustomSharedPreferencePath;
import utils.FormateUtils;
import utils.LoginRedCountUtils;
import utils.ObjectSaveUtil;
import utils.PopupWindowUtil;
import utils.SerialPortUtil;
import utils.TimeUtil;
import utils.ToastUtil;

public class CheckActivity extends BaseActivity implements CheckFragment.CkeckInterface, CheckErrorFragment.CheckErrorInterface, TakeErrorFragment.TakeErrorInterface, TakeFragment.TakeInterface {

    @BindView(R.id.iv_check_home)
    ImageView ivCheckHome;
    @BindView(R.id.fl_check_empty)
    FrameLayout flEmpty;
    //    @BindView(R.id.iv_check_back)
//    ImageView ivBack;
    private String saveFileName = "CheckDecrementLog";
    private MediaPlayer mediaPlayer;
    private List<Fragment> fragmentList = new ArrayList<>();

    private SQLiteDatabase database;
    private ArrayList<String> rfidCodeList = new ArrayList<>();

    private CommonStateErrorAdapter errorAdapter;
    private List<OperateGoodsDetailsBean.DataBean> errorList = new ArrayList<>();
    private List<OperateGoodsDetailsBean.DataBean> list = new ArrayList<>();
    private int selectCabinet;
    private List<OperateGoodsDetailsBean.DataBean> errorGoodsList = new ArrayList<>();
    private boolean isFirst = true;
    private NewUserInfoBean.DataBean userInfoBean;
    private String useDeptment;
    private List<CheckSureBean> checkSureList = new ArrayList<>();
    private MyHandler allHandler;
    private StringBuilder sb = new StringBuilder();
    private Map<Integer, String> hashMap;

    //用于表明操作SQL的次数,全部操作完成,才能去获取SQL中的数据,并显示(用于非第一次验收)
    private int operateSQLCount;
    private int errorCount, correctCount;
    private CheckFragment checkFragment;
    private CheckErrorFragment checkErrorFragment;
    private PopupWindow mPopupWindow;
    private Map<String, OperateGoodsDetailsBean.DataBean> errorMap = new HashMap<>();
    private SharedPreferences sharedPreferences;
    private int count;
    private int takeCount;
    private int takeErrorCount;
    private List<OperateGoodsDetailsBean.DataBean> takeList = new ArrayList<>();
    private List<OperateGoodsDetailsBean.DataBean> takeErrorList = new ArrayList<>();
    private TakeFragment takeFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_check);
        ButterKnife.bind(this);
        Constants.CHECKING = true;
    }

    @OnClick({R.id.iv_check_home})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_check_home:
                database.execSQL("delete from goodsInfo");
                finish();
                break;
//            case R.id.iv_check_back:
//                finish();
//                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Constants.CHECKING = false;
    }

    @Override
    public void initView() {
        super.initView();
        selectCabinet = getIntent().getIntExtra(Constants.CHECK_ACTIVITY, 0);
        isFirst = getIntent().getBooleanExtra(Constants.CHECK_ACTIVITY_ISFIRST, true);
        sharedPreferences = ActivityUtil.getSharedPreferences(this);
        Map<String, OperateGoodsDetailsBean.DataBean> recordList = (Map<String, OperateGoodsDetailsBean.DataBean>) CustomSharedPreferencePath.getData(this, Constants.RECORD_ERROR_GOODS, null);

        if (recordList != null) {
            errorMap = recordList;
        }

        useDeptment = NetAddress.deptCode;

        userInfoBean = (NewUserInfoBean.DataBean) ObjectSaveUtil.readObject(CheckActivity.this, Constants.USER_INFO_BEAN, Constants.USER_INFO_BEAN);

        allHandler = SingletonClass.getSingleton(MyHandler.class);
        showLoadingView(flEmpty);

        database = MySQLiteOpenHelper.getDatabase(CheckActivity.this);
        Log.e(TAG, "initView: " + getFromSql().size());
        Object o = ObjectSaveUtil.readObject(this, Constants.CABINETINFO_LOGICNUMBER_HASHMAP, Constants.CABINETINFO_LOGICNUMBER_HASHMAP);
        sb.delete(0, sb.length());
        if (o != null) {
            hashMap = (Map<Integer, String>) o;
            Set set = hashMap.entrySet();
            Iterator iterator = set.iterator();
            while (iterator.hasNext()) {
                Map.Entry mapentry = (Map.Entry) iterator.next();
                sb.append("'" + mapentry.getKey() + "',");
            }
            sb.deleteCharAt(sb.length() - 1);
        }

    }

    @Override
    protected void onHandleMessage(Message msg) {
        super.onHandleMessage(msg);
        switch (msg.what) {
            case HandlerConstant.SCAN_COMPLETE:
                scanComplete(msg);
                break;
            case HandlerConstant.SCAN_COMPLETE_ERROR:

                if (isFirst) {
                    //第一次验收没有数据
                    finish();
                } else {
                    //    非第一次验收,没有数据,则从sqlite拿取数据
                    rfidCodeList = getFromSql();
                    if (rfidCodeList.size() > 0) {
                        getGoodsDetails(rfidCodeList, "", "1");
                    } else {
                        finish();
                    }
                }
                break;

            case HandlerConstant.OPERATE_SQL_SUCCESS:
                operateSQLCount--;
                //等于0代表操作sql完成
                if (operateSQLCount == 0) {
                    rfidCodeList = getFromSql();
                    Log.e(TAG, "onHandleMessage: rfidCodeList  " + rfidCodeList.size());
                    if (rfidCodeList.size() > 0) {
                        getGoodsDetails(rfidCodeList, "", "1");
                    } else {
                        finish();
                    }
                    sendEmptyMessage(HandlerConstant.FINISH_NETWORK);
                }
                break;

        }
    }

    private void scanComplete(Message msg) {

        //扫描完成之后,请求数据库
        String s = (String) msg.obj;
        Log.e(TAG, "call: " + s);
        String[] split = s.split(Constants.INCREASE_DECREASE_SPLIT);

        // 记录验收时单片机给的 减量
        if (split.length == 2) {
            SerialPortUtil.saveToFile("decrement RFID ： " + split[1], saveFileName);
        }

        //第一次验收
        if (isFirst) {
            if (split.length >= 1) {
                if (!TextUtils.isEmpty(split[0])) {
                    rfidCodeList = FormateUtils.getRfidCodes(split[0]);
                    getGoodsDetails(rfidCodeList, "", "1");
                    insertIntoSql(rfidCodeList);
                    Log.e(TAG, "第一次验收 放入");
                }else {
                    finish();
                }
            }
        } else {
            //非第一次验收
            if (split.length == 1) {
                Log.e(TAG, "非第一次验收 放入");
                operateSQLCount = 1;
                insertIntoSql(FormateUtils.getRfidCodes(split[0]));
            } else if (split.length == 2) {
                if (!TextUtils.isEmpty(split[0])) {
                    operateSQLCount = 2;
                    insertIntoSql(FormateUtils.getRfidCodes(split[0]));
                } else {
                    operateSQLCount = 1;
                }
                deleteFromSql(FormateUtils.getRfidCodes(split[1]));
                Log.e(TAG, "非第一次验收 取出");
            }

        }

//        if (split.length == 2) {
//            if (!TextUtils.isEmpty(split[1])) {
//                Log.e(TAG, "取出: ");
//                //根据RFIDCODE从服务器获取取出(即单片机减少的)的相关信息
//                ArrayList<String> takes = FormateUtils.getRfidCodes(split[1]);
//                operaGoodsDetails(takes, selectCabinet + "", 4);
//            } else {
//                sendEmptyMessage(HandlerConstant.FINISH_NETWORK);
//            }
//        } else {
//            sendEmptyMessage(HandlerConstant.FINISH_NETWORK);
//        }
    }

    //获取相关RFID信息
    private void getGoodsDetails(final ArrayList<String> rfidList, final String cabinetCode, final String type) {
        GetRetrofit.getInstance().getGoodDetails(NetAddress.token, NetAddress.machineCode, rfidList, "", cabinetCode, type)
                .subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<OperateGoodsDetailsBean>() {
            @Override
            public void call(OperateGoodsDetailsBean goodsDetailsBean) {
                hideLoadingView();
                errorGoodsList.clear();
                List<OperateGoodsDetailsBean.DataBean> dataBean = goodsDetailsBean.getData();
                List<OperateGoodsDetailsBean.DataBean> aberrantData = goodsDetailsBean.getAberrantData();
                if (dataBean != null && dataBean.size() > 0) {
                    correctCount = dataBean.size();
                    list = FormateUtils.getDistinctList(dataBean, selectCabinet);
                }
                if (aberrantData != null && aberrantData.size() > 0) {
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < aberrantData.size(); i++) {
                        OperateGoodsDetailsBean.DataBean bean = aberrantData.get(i);
                        // 记录异常物资的RFID 和状态
                        sb.append(bean.getRfidCode() + "--" + bean.getStatus()+ ",");
                    }
                    SerialPortUtil.saveToFile("abnormal RFID : " + sb.toString(),saveFileName);

                    errorGoodsList.addAll(aberrantData);
                    errorCount = aberrantData.size();
                    errorList = FormateUtils.getDistinctList(aberrantData, selectCabinet);
                }
                Log.e(TAG, "call: " + rfidList.size() + "   " + correctCount + "   " + errorCount);
                if (list.size() > 0 || errorList.size() > 0) {
                    if (errorList.size() > 0) {
                        mediaPlayer = MediaPlayer.create(CheckActivity.this, R.raw.check_error);
                    } else {
                        mediaPlayer = MediaPlayer.create(CheckActivity.this, R.raw.check_close);
                    }
                    int sound = sharedPreferences.getInt(Constants.SOUND_KEY, 50);
                    Float div = FormateUtils.div(sound, 100, 1);
                    mediaPlayer.setVolume(div,div);
                    mediaPlayer.start();
                } else {
                    finish();
                }
                Log.e(TAG, "call: initFragment" );
                initFragment();

            }
        }, new MyAction1() {
            @Override
            public void call(Throwable throwable) {
                super.call(throwable);
                finish();
                ToastUtil.showToast(CheckActivity.this, "网络请求错误!" + throwable.getMessage());
            }
        });
    }

    //点击确认验收之后,调用此接口,通知后台更改日志
    private void operaGoodsDetails(final ArrayList<String> rfidList, String cabinetCode, final int type) {
        GetRetrofit.getInstance().operateGoodDetails(NetAddress.token, NetAddress.machineCode, rfidList, NetAddress.terminalInfoId, cabinetCode, userInfoBean.getID(), type)
                .subscribeOn(Schedulers.io())
                .retryWhen(new NetReconnectFunc1())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<OperateGoodsDetailsBean>() {
                    @Override
                    public void call(OperateGoodsDetailsBean bean) {
                        if (bean.getData() != null && bean.getData().size() != 0) {
                            for (int i = 0; i < bean.getData().size(); i++) {
                                OperateGoodsDetailsBean.DataBean dataBean = bean.getData().get(i);
                                CheckSureBean checkSureBean = new CheckSureBean();
                                checkSureBean.setRfidCode(dataBean.getRfidCode());
                                checkSureBean.setManufacturerCode(dataBean.getManufacturerCode());
                                checkSureBean.setMaterialCode(dataBean.getMaterialCode());
                                checkSureBean.setRecordNo(dataBean.getRecordNo());
                                checkSureBean.setStoreCode(dataBean.getStoreCode());
                                checkSureBean.setUseDeptment(useDeptment);
                                checkSureList.add(checkSureBean);
                            }

                            if (Constants.IS_FUYI) {
                                GetRetrofit.getInstance2().checkToHospital(checkSureList).subscribeOn(Schedulers.io()).retryWhen(new NetReconnectFunc1()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<List<CheckHospitalBean>>() {
                                    @Override
                                    public void call(List<CheckHospitalBean> checkHospitalBeen) {
                                        String id;
                                        if (userInfoBean.getRoleInfoId() != 1 && userInfoBean.getRoleInfoId() != 4) {
                                            id = "0";
                                        } else {
                                            id = userInfoBean.getID() + "";
                                        }
                                        LoginRedCountUtils.getLoginDataCount(CheckActivity.this, id, NetAddress.deptCode, false);
                                        ToastUtil.showToast(CheckActivity.this, "验收成功!");
                                        addErrorGoods();
                                        finish();
                                    }
                                }, new MyAction1() {
                                    @Override
                                    public void call(Throwable throwable) {
                                        ToastUtil.showToast(CheckActivity.this, "医院网络请求失败");
                                    }
                                });
                            } else {
                                ToastUtil.showToast(CheckActivity.this, "验收成功!");
                                finish();
                            }
                        }
                    }
                }, new MyAction1() {
                    @Override
                    public void call(Throwable throwable) {
                        ToastUtil.showToast(CheckActivity.this, "接口网络请求失败");
                    }
                });
    }

    private void addErrorGoods() {

        for (int i = 0; i < errorGoodsList.size(); i++) {
            OperateGoodsDetailsBean.DataBean dataBean = errorGoodsList.get(i);
            dataBean.setSelectCabinet(selectCabinet + "");
            dataBean.setErrorRecordTime(TimeUtil.getMillisecondDate());
            if (dataBean.getStatus() != 3) {
                String key = dataBean.getGID() + dataBean.getSpecification() + dataBean.getManufacturer() + dataBean.getStatus();
                if (errorMap.get(key) != null) {
                    String millisecondDate = TimeUtil.getMillisecondDate();
                    OperateGoodsDetailsBean.DataBean bean = errorMap.get(key);
                    bean.setSelectCabinet(selectCabinet + "");
                    bean.setNumber(bean.getNumber() + 1);

                    bean.setErrorRecordTime(millisecondDate);
                    if (!bean.getBarCodeList().contains(dataBean.getBarCode())) {
                        bean.getBarCodeList().add(dataBean.getBarCode() + Constants.INCREASE_DECREASE_SPLIT + millisecondDate);
                    }
                    errorMap.put(key, bean);
                } else {
                    Log.e("test", "addErrorGoods: " + key );
                    dataBean.setErrorRecordTime(TimeUtil.getMillisecondDate());
                    errorMap.put(key, dataBean);
                }
            }
        }

        allHandler.sendEmptyMessage(HandlerConstant.ERROR_MODIFY);
        CustomSharedPreferencePath.saveData(this, Constants.RECORD_ERROR_GOODS, errorMap);
    }

    private void deleteErrorGoods() {
        for (int i = 0; i < errorGoodsList.size(); i++) {
            OperateGoodsDetailsBean.DataBean dataBean = errorGoodsList.get(i);
            String key = dataBean.getGID() + dataBean.getSpecification() + dataBean.getManufacturer() + dataBean.getStatus();
            dataBean.setSelectCabinet(selectCabinet + "");
            if (errorMap.get(key) != null) {
                Log.e(TAG, "deleteErrorGoods: " + hashMap.size() + "   " + key);
                OperateGoodsDetailsBean.DataBean bean = errorMap.get(key);
                bean.setSelectCabinet(selectCabinet + "");
                if (bean.getNumber() > 1) {
                    bean.setNumber(bean.getNumber() - 1);
                } else {
                    bean.setNumber(0);
                }

                bean.getBarCodeList().remove(dataBean.getBarCode() + Constants.INCREASE_DECREASE_SPLIT + dataBean.getErrorRecordTime());
                errorMap.put(key, bean);
//                }
            } else {
                Log.e(TAG, "null: " + hashMap.size() + "   " + key);
            }
        }

        CustomSharedPreferencePath.saveData(this, Constants.RECORD_ERROR_GOODS, errorMap);
    }

    private void initFragment() {
        checkFragment = new CheckFragment();
        checkErrorFragment = new CheckErrorFragment();
        takeFragment = new TakeFragment();
        TakeErrorFragment takeErrorFragment = new TakeErrorFragment();

        Bundle takeBundle = new Bundle();
        takeBundle.putString("count", takeCount + "");
        RfidListBean takeBean = new RfidListBean();
        takeBean.setList(takeList);
        takeBundle.putSerializable(Constants.TAKE_FRAGMENT, takeBean);
        takeFragment.setArguments(takeBundle);

        Bundle takeErrorBundle = new Bundle();
        takeErrorBundle.putString("count", takeErrorCount + "");
        RfidListBean takeErrorBean = new RfidListBean();
        takeErrorBean.setList(takeErrorList);
        takeErrorBundle.putSerializable(Constants.TAKE_ERROR_FRAGMENT, takeErrorBean);
        takeErrorFragment.setArguments(takeErrorBundle);

        Bundle checkBundle = new Bundle();
        RfidListBean bean = new RfidListBean();
        bean.setList(list);
        checkBundle.putSerializable(Constants.CHECK_FRAGMENT, bean);
        checkBundle.putString("count", correctCount + "");
        checkFragment.setArguments(checkBundle);

        Bundle checkErrorBundle = new Bundle();
        RfidListBean bean1 = new RfidListBean();
        bean1.setList(errorList);
        checkErrorBundle.putSerializable(Constants.CHECK_ERROR_FRAGMENT, bean1);
        checkErrorBundle.putString("count", errorCount + "");
        checkErrorFragment.setArguments(checkErrorBundle);

        if (takeErrorList.size() != 0) {
            selectFragment(takeErrorFragment);
        } else if (takeList.size() != 0) {
            selectFragment(takeFragment);
        } else if (errorList.size() != 0) {
            selectFragment(checkErrorFragment);
        } else if (list.size() != 0) {
            selectFragment(checkFragment);
        } else {
            finish();
        }
    }

    //验收的时候,将数据保存起来(若用户点击返回,重新验收,会用到这些数据)
    private void insertIntoSql(ArrayList<String> rfidCodeList) {
        Observable.from(rfidCodeList).doOnSubscribe(new Action0() {
            @Override
            public void call() {
                database.beginTransaction();
            }
        }).doOnNext(new Action1<String>() {
            @Override
            public void call(String s) {
                database.execSQL("insert into goodsInfo (epc) values ('" + s + "')");
            }
        }).last().subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                database.setTransactionSuccessful();
                database.endTransaction();
                sendEmptyMessage(HandlerConstant.OPERATE_SQL_SUCCESS);
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                database.endTransaction();
            }
        });
    }

    private ArrayList<String> getFromSql() {
        ArrayList<String> sqlList = new ArrayList<>();
        Cursor cursor = database.query("goodsInfo", new String[]{"epc"}, null, null, null, null, null);
        int epc = cursor.getColumnIndex("epc");
        for (cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()) {
            sqlList.add(cursor.getString(epc));
        }
        Log.e(TAG, "getFromSql: " + sqlList.size());
        return sqlList;
    }

    private void deleteFromSql(ArrayList<String> rfidCodeList) {
        Observable.from(rfidCodeList).doOnNext(new Action1<String>() {
            @Override
            public void call(String s) {
                database.execSQL("delete from goodsInfo where epc = '" + s + "'");
            }
        }).last().subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                sendEmptyMessage(HandlerConstant.OPERATE_SQL_SUCCESS);
            }
        }, new MyAction1() {
            @Override
            public void call(Throwable throwable) {
                super.call(throwable);
                Log.e(TAG, "call: " + throwable.getMessage());
            }
        });
    }

    @Override
    public void checkReturn() {
        Message message = allHandler.obtainMessage();
        message.obj = selectCabinet;
        message.what = HandlerConstant.CHECK_AGAIN;
        allHandler.sendMessage(message);
        Intent intent = new Intent(CheckActivity.this, OpenDoorRemindActivity.class);
        intent.putExtra(Constants.OPEN_DOOR_CABINET, selectCabinet);
        intent.putExtra(Constants.OPEN_DOOR_REMIND, Constants.CHECK_AGAIN);
        startActivity(intent);
        finish();
    }

    @Override
    public void checkSure() {
        //点击确定之后,写到医院数据库
        operaGoodsDetails(rfidCodeList, String.valueOf(selectCabinet), 2);
        database.execSQL("delete from goodsInfo");
        allHandler.sendEmptyMessage(HandlerConstant.CHECK_SURE);
    }

    @Override
    public void checkErrorSure() {
        if (list.size() != 0) {
            selectFragment(checkFragment);
        } else {
            addErrorGoods();
            finish();
        }
    }

    private void selectFragment(Fragment fragment) {
        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
        transaction.replace(R.id.fl_check_empty, fragment);
        transaction.commit();
    }

    @Override
    public void takeErrorSure() {
        if (takeList.size() != 0) {
            selectFragment(takeFragment);
        } else if (errorList.size() != 0) {
            selectFragment(checkErrorFragment);
        } else if (list.size() != 0) {
            selectFragment(checkFragment);
        } else {
            finish();
        }
    }

    @Override
    public void takeSure() {
        if (errorList.size() != 0) {
            selectFragment(checkErrorFragment);
        } else if (list.size() != 0) {
            selectFragment(checkFragment);
        } else {
            finish();
        }
    }
}